import { _decorator, Component, Node, tween, v3 } from 'cc';
import { BaseView } from '../../libs/rxjs/cc3/BaseView';
import { Observable } from '../../libs/rxjs/internal/Observable';
import { linear } from '../../libs/utils/math';
import { of } from 'rxjs';
const { ccclass, property } = _decorator;

@ccclass('CameraShake')
export class CameraShake extends BaseView {

    @property
    shakeEnabled = true;

    useObserves() {
        return [
            // gm.cameraShakeCommand.subscribe(_ => {
            //     switch (_) {
            //         case 'blackhole':
            //             this.shakeObservable(20, 20, .12, false, .2).subscribe();
            //             break;
            //     }
            // })
        ];
    }

    shakeObservable(maxAmp = 30, repeat = 8, _period = .1, cslow = false, delay = 0) {

        if (this.shakeEnabled) {
            [this.node].forEach(_node => {
                //@ts-ignore
                let oldTween = _node._shake_tween;
                if (oldTween != null) {
                    oldTween.stop();
                    //@ts-ignore
                    delete _node._shake_tween
                }
            })

            return new Observable(observer => {
                let mytween = tween(this.node);
                let rad = Math.random() * Math.PI * 2;

                let period = _period;

                if (delay > 0) {
                    mytween.delay(delay);
                }

                for (let i = 0; i < repeat; i++) {
                    let inx = linear(0, repeat, -1, 0, i);
                    let out = inx * inx;
                    let amp = maxAmp * out;
                    let x = Math.cos(rad) * amp;
                    let y = Math.sin(rad) * amp;

                    if (cslow) {
                        period = _period * 1.1 * (i + 1);
                    }

                    if (mytween == null) {
                        mytween = mytween.to(period / 2, { position: v3(x, y, 0) }, { easing: 'sineOut' });
                    } else {
                        mytween = mytween.to(period, { position: v3(x, y, 0) }, { easing: 'sineInOut' });
                    }
                    let pi_5_4 = 5 * Math.PI / 4;
                    let pi_3_4 = 3 * Math.PI / 4;
                    rad += Math.random() * (pi_5_4 - pi_3_4) + pi_3_4;
                }
                mytween = mytween.to(period / 2, { position: v3(0, 0, 0) }, { easing: 'sineInOut' });

                let tween1 = mytween.call(() => {
                    observer.next('fin');
                    observer.complete();
                }).start();

                this.node.attr({
                    _shake_tween: tween1
                });
            });
        } else {
            return of('fin');
        }
    }

}


